import { Modal, Radio } from "antd"
import React, { memo, useCallback, useEffect, useReducer, useState } from "react"
import styled from "styled-components"
const [width, height] = [1200, 800]
import withGame from "@/hooks/with-game"
const reducer = (state, message) => {
    switch (message.command) {
        case "start":
            return {
                pokers: sortPoker(message.data.cards.map(type =>
                    ({ type, state: false }))),
                players: [
                    17,//上家
                    17//下家
                ],
                next: message.data.next,
                msgStack: [],
                minScore: 0,
                scoreNum: 0,
                myId: message.pid,
                leftover: [],//底牌
                landlord: null,
            }
        case "call":
            state.next = (state.next + 1) % 3
            state.scoreNum++;
            state.minScore = Math.max(message.score, state.minScore);
            state.msgStack.push({
                type: "text",
                msg: message.pid + " 阔了 " + message.score + " 分"
            })
            return { ...state }
        case "kuo":
            state.landlord = message.pid;
            state.leftover = message.cards;
            if (state.myId === message.pid) {
                state.pokers = sortPoker(state.pokers.concat(message.cards.map((type) => ({ type, state: true }))))
            } else {
                const index = +((state.myId + 1) % 3 === message.pid)
                state.players[index] += 3
            }
            state.next = message.pid
            state.msgStack.push({
                type: "text",
                msg: message.pid + "获得了地主",
                pid: message.pid
            })
            return { ...state }
        case "act":
            state.msgStack.push({
                type: "poker",
                cards: message.cards,
                pid: 1 + +(message.pid != state.landlord)
            })
            if (state.myId === message.pid) {
                state.pokers = state.pokers.filter((item) => {
                    return !message.cards.some(e => e == item.type)
                })
            } else {
                const index = +((state.myId + 1) % 3 === message.pid)
                state.players[index] -= message.cards.length
                if (state.players[index] <= 0) {
                    setTimeout(() => {
                        alert(message.pid + "出完牌了")
                    }, 1000)
                    setTimeout(() => {
                        window.location.reload()
                    }, 5000)
                }
            }
            state.next = state.next === 2 ? 0 : state.next + 1;
            return { ...state }
        case "select":
            for (const key of message.keys) {
                console.log(state.pokers[key].state)
                state.pokers[key].state = !state.pokers[key].state
                console.log(state.pokers[key].state)
            }
            return { ...state, pokers: state.pokers }
        default:
            return state
    }
}
interface stateType {
    pokers: any[],
    players: number[],
    next: number,
    msgStack: [],
    minScore: number,
    scoreNum: number,
    myId: number,
    leftover: [],
    landlord: number
}
const Container = styled.div`
    position:relative;
    width:${width}px;
    height:${height}px;
    margin:auto;
`
const PokerImage = ({
    width,
    height,
    state,
    mousedown,
    src
}) => {
    const PokerImage = styled.img`
        width:${width}px;
        height:${height}px;
    `
    const PokerImageBox = styled.div`
        width:${width / 2}px;
        height:${height}px;
        margin-top:${-state * 20}px;
    `
    return (
        <PokerImageBox
            onMouseDown={mousedown}
        >
            <PokerImage src={src} />
        </PokerImageBox>
    )
}
const pokerWidth = 100;
const pokerHeight = 150;
const PokerImageContainer = styled.div<{ width: number, top: number }>`
    position:absolute;
    left:calc(50% - ${props => props.width / 2}px);
    top:${props => props.top}px;
    width:${props => props.width}px;
    display:flex;
    justify-content: center;
`
const getPictureId = (num) => num == 16 ? 2 :
    num == 17 ? 1 :
        num % 100 + (Math.floor(num / 100) - 1) * 13;
const StyledCall = ({ bool, send, pokers }: any) => {
    const CallContainer = styled.div`
        position:relative;  
        width:100px;
        height:40px;
        text-align:center;
        line-height:40px;
        left:calc(50% - 50px);
        top:${height - pokerHeight - 150}px;
        display:flex;
    `
    const Call = styled.div`
        width:40px;
        margin-left:5px;
        margin-right:5px;
        background:#ccc;
        border-radius:10px;
        :hover{
            background:#3f51b5;
        }
        cursor:pointer;
        transition:.4s;
    `
    if (!bool) return <></>;
    return (
        <CallContainer>
            <Call onClick={() => send({
                command: "act",
                cards: []
            })
            }>不出</Call>
            <Call onClick={() => send({
                command: "act",
                cards: pokers.filter(({ state }) => state).map(({ type }) => type)
            })}>出牌</Call>
        </CallContainer>
    )
}
const createScore = (start = 0, send) => {
    let score = 0;
    const Content = () => {
        const arr = [0, ...Array.from(new Array(4).keys()).slice(start + 1)]
        return (
            <Radio.Group defaultValue={0} onChange={({ target: { value } }) => score = value}>
                {arr.map((key) => (
                    <Radio key={key} value={key}>
                        {key}分
                    </Radio>
                ))}
            </Radio.Group>
        )
    }
    Modal.info({
        onOk() {
            send({
                command: "call",
                score
            })
        },
        content: <Content />,
        okText: "阔哥牛逼"
    })
}
const Avatar = ({ landord, left, id, num }) => {
    const Content = styled.div`
        width:50px;
        height:50px;
        position:absolute;
        top:50px;
        left:${left}px;
        background-image:url(/pokers/${1 - -!landord}.jpg);
        background-size:100% 100%;
        line-height:50px;
        color:#fff;
        font-size:32px;
        text-align:center;
    `
    return (
        <Content>
            {id}-{num}
        </Content>
    )
}
const sortPoker = (cards: any[]) => cards.sort((a, b) => ((b.type % 100) * 10 + (b.type / 100 | 0)) - ((a.type % 100) * 10 + (a.type / 100 | 0)))
const ddz = withGame(({ message, send }) => {
    const [state, setState] = useState<stateType>(null)
    useEffect(() => {
        const result = reducer(state, message)
        if (result != state) {
            setState(result)
        }
    }, [message])
    useEffect(() => {
        if (!state) return;
        if (state.landlord == null && state.minScore != 3 && state.scoreNum != 3) {
            if (state.myId === state.next) {
                createScore(state.minScore, send)
            }
        }
    }, [state])
    const click = useCallback((event, key: number) => {
        state.pokers[key].state = !state.pokers[key].state
        setState({ ...state })
    }, [state])
    if (!state) return <div />
    const MsgStackContext = () => {
        if (!state) return;
        const arr = new Array(3)
            .fill(null)
            .concat(state.msgStack.slice(-3)).slice(-3)
        const StackContainer = styled.div`
            width:80%;
            height:300px;
            margin:auto;
            position:absolute;
            top:200px;
        `
        const StackItem = styled.div`
            width:100%;
            height:100px;
            text-align:center;
            line-height:100px;
            display:flex;
        `
        const StackIcon = styled.img`
            width:100px;
            height:100px;
        `
        const StackImageContainer = styled.div`
            width:100%;
            display:flex;
            justify-content: center;
        `
        return (
            <StackContainer>
                {arr.map((item, key) => {
                    if (!item) return <StackItem key={key} />
                    if (item.type === "text") {
                        return (
                            <StackItem key={key}>
                                {item.msg}
                            </StackItem>
                        )
                    }
                    if (item.type === "poker") {
                        return (
                            <StackItem key={key}>
                                <StackIcon src={`/pokers/${item.pid}.jpg`} />
                                <StackImageContainer >
                                    {item.cards.map((num, k) => (
                                        <PokerImage
                                            key={`1-${k}`}
                                            width={pokerWidth / 2}
                                            height={pokerHeight / 2}
                                            state={false}
                                            mousedown={null}
                                            src={`/pokers/${getPictureId(num)}.jpg`}
                                        />
                                    ))}
                                </StackImageContainer>
                            </StackItem>
                        )
                    }
                })}
            </StackContainer>
        )
    }
    const leftId = (state.myId + 1) % 3
    const rightId = (leftId + 1) % 3
    return (
        <Container>
            <Avatar
                landord={leftId === state.landlord}
                left={width - 100}
                id={leftId}
                num={state.players[0]}
            />
            <Avatar
                landord={rightId === state.landlord}
                left={50}
                id={rightId}
                num={state.players[1]}
            />
            <PokerImageContainer
                width={300}
                top={20}
            >
                {state.leftover.map((item, key) => (
                    <PokerImage
                        key={key}
                        state={false}
                        width={100}
                        height={100}
                        src={`/pokers/${getPictureId(item)}.jpg`}
                        mousedown={null}
                    />
                ))}
            </PokerImageContainer>
            <StyledCall
                pokers={state.pokers}
                send={send}
                bool={state.next == state.myId && null != state.landlord} />
            <MsgStackContext />
            <PokerImageContainer
                width={1200}
                top={height - pokerHeight - 50}
            >
                {state.pokers.map(({ type, state }, key) => (
                    <PokerImage
                        key={key}
                        state={state}
                        width={pokerWidth}
                        height={pokerHeight}
                        src={`/pokers/${getPictureId(type)}.jpg`}
                        mousedown={(e) => click(e, key)}
                    />
                ))}
            </PokerImageContainer>

        </Container>
    )
}, 3)
export default ddz